var widget = widget || {};
/**
 * Это класс виджета кнопки.
 * Copyright 2012, Alexander Dashkovsky
 * License: http://www.opensource.org/licenses/mit-license.php
 * @lends widget.Button
 */
widget.Button = Base.extend({

	/** @const */
	WIDGET_CLASS : 'wg_button',
	
	text : undefined,
	
	iconCls : undefined,
	
	/**
	 * Конструктор класса
	 * @augments Base
	 * @class Класс виджета кнопки с текстом и иконкой.
	 *
	 * <p><b>CSS класс для DOM элемента - <code>wg_button</code></b></p>
	 * 
	 * <p><b>Параметры объекта конфигурации:</b></p>
	 * {String} <b>id</b> - Идентификатор компонента кнопки.<br />
	 * {String} <b>cls</b> - Имя класса css (или нескольких классов через пробел)
	 * которые будут добавлены кнопке.<br />
	 * {String} <b>iconCls</b> - Имя класса css изображения, которое будет 
	 * присутствовать на кнопке.<br />
	 * {Int} <b>text</b> - Текст на кнопке.<br />
	 * {Int} <b>width</b> - Ширина кнопки. Если этот атрибут не задан, ширина
	 * кнопки будет вычислена исходя из размера иконки и длины текста.<br />
	 * {ElementDOM} <b>renderTo</b> - Элемент DOM, в который будет прорисована кнопка.<br />
	 * {Object[]} <b>listeners</b> - Массив слушателей событий.<br />
	 * 
	 * <p><b>События:</b></p>
	 * <div><b>afterrender</b> - Вызывается сразу после прорисовки кнопки.</div>
	 * <div class="shift1">callbackFunction(<b>component</b>, <b>domElement</b>), где:</div>
	 * <div class="shift2"><b>component</b> - компонент кнопки</div>
	 * <div class="shift2"><b>domElement</b> - DOM элемент кнопки</div>
	 * <div><b>click</b> - Вызывается при клике на область кнопки.</div>
	 * <div class="shift1">callbackFunction(<b>component</b>, <b>domElement</b>), где:</div>
	 * <div class="shift2"><b>component</b> - компонент кнопки</div>
	 * <div class="shift2"><b>domElement</b> - DOM элемент кнопки</div>
	 * <div><b>hide</b> - Вызывается когда кнопка была спрятана.</div>
	 * <div class="shift1">callbackFunction(<b>component</b>, <b>domElement</b>), где:</div>
	 * <div class="shift2"><b>component</b> - компонент кнопки</div>
	 * <div class="shift2"><b>domElement</b> - DOM элемент кнопки</div>
	 * <div><b>show</b> - Вызывается когда кнопка была показана.</div>
	 * <div class="shift1">callbackFunction(<b>component</b>, <b>domElement</b>), где:</div>
	 * <div class="shift2"><b>component</b> - компонент кнопки</div>
	 * <div class="shift2"><b>domElement</b> - DOM элемент кнопки</div>
	 * 
	 * <p><b>Пример:</b></p>
	 * Две кнопки располагаются друг за другом горизонтально. 
	 * Первая кнопка с иконкой и текстом, вторая только с иконкой.
	 * <pre class="code">
	 * var btnSave = new widget.Button({
	 * 	id : 'btn1',
	 * 	cls : 'myBtn',
	 * 	iconCls : 'ui-icon-disk',
	 * 	text : 'Сохранить',
	 * 	width : 140,
	 * 	renderTo : $('#controls'),
	 * 	listeners : {
	 * 		click : function(field, elementDom){
	 * 			console.log('button Save click!');
	 * 		}
	 * 	}
	 * });
	 * 
	 * var btnHome = new widget.Button({
	 * 	id : 'btn2',
	 * 	cls : 'myBtn',
	 * 	iconCls : 'ui-icon-home',
	 * 	renderTo : $('#controls'),
	 * 	listeners : {
	 * 		click : function(field, elementDom){
	 * 			console.log('button Home click!');
	 * 		}
	 * 	}
	 * });
	 * 
	 * </pre>
	 * 
	 * @constructs
	 * @param {object} config Описатель кнопки.
	 * @param {String} config.id Идентификатор компонента кнопки.
	 * @param {String} config.cls Имя класса css (или нескольких классов через пробел)
	 * которые будут добавлены кнопке.
	 * @param {String} config.iconCls Имя класса css изображения, которое будет 
	 * присутствовать на кнопке.
	 * @param {Int} config.text Текст на кнопке.
	 * @param {Int} config.width Ширина компонента.
	 * @param {ElementDOM} config.renderTo Элемент DOM, в который будет 
	 * прорисована кнопка.</br>
	 * @param {Object[]} config.listeners Массив слушателей событий
	 */
	constructor : function(config) {
		this.config = config || {} ;
		this.text = this.config.text;
		this.iconCls = this.config.iconCls;
		if (this.config.renderTo) {
			this.render(this.config.renderTo);
		}
	},
	
	/**
	 * Выполняется отрисовка кнопки.
     * @public 
	 * @function
     * @memberOf widget.Button#
	 * @param {elementDOM} renderTo Элемент DOM, внутри которого будет 
	 * создана кнопка.
	 * Если этот параметр не задавать, а поле уже ранее прорисовывалось, то оно 
	 * будет перерисоваться в тот же контейнер. Если в контейнере существуют и 
	 * другие виджеты, render() без параметра прорисует этот виджет после всех 
	 * остальных.
	 * @return none
	 */
	render : function(renderTo) {
		var me = this;
		if (this.element) {
			this.element.remove();
		}

		if (renderTo) {
			this.renderContainer = renderTo;
		} else {
			renderTo = this.renderContainer;
		}
		
		var options = {};

		var tpl = '<div  class="windgetButton">';
		if (this.config.text) {
			tpl += '' + this.config.text + '';
		} else {
			tpl += '<span>&nbsp;</span>';
			options.text = false;
		}
		tpl += '</div>';

		if (this.element) {
			this.element.remove();
		}
		this.element = $(tpl);
		
		if (this.config.width) {
			this.element.width(this.config.width);
		}	
		
		if (this.config.cls) {
			this.applyClassToElement(this.config.cls, this.element);
		}
		if (this.config.overCls) {
			this.applyOverClassToElement(this.config.overCls, this.element);
		}
		if (this.config.iconCls) {
			options.icons = { primary: this.config.iconCls};
		}
		
		this.buttonText = $(this.element).find("span");

		if (this.config.width) {
			this.element.width(this.config.width);
		}
		
		if (this.config.height) {
			this.element.height(this.config.height);
		}
		
		if (renderTo) {
			$(this.element).appendTo(renderTo);
			this.element.button(options);
			$(this.element).click(function(event) {
				me.onClick(event);
				event.preventDefault();
				return false;
			});
			this.onAfterRender();
		}
	},
	
	/**
	 * Функция добавляет класс(классы) к элементу.
     * @function
     * @private 
	 */
	applyClassToElement : function(cls, element) {
		if (cls) {
			var arr = cls.split(' ');
			for (var i=0; i<arr.length; i++) {
				$(element).addClass(arr[i]);
			}
		}
	},
	
	/**
	 * Функция отрабатывает сразу после прорисовки конпонента. 
     * @private 
	 * @function
	 */
	onAfterRender : function() {
		if (this.config.listeners && this.config.listeners.afterrender) {
			this.config.listeners.afterrender(this, this.element);
		}
	},
	
	/**
	 * Функция отрабатывает сразу после клика мышки на компоненте. 
     * @private 
	 * @function
	 */
	onClick : function(event) {
		if (this.config.listeners && this.config.listeners.click) {
			this.config.listeners.click(this, this.element, event);
		}
		//(window.event) ? event.cancelBubble = true : event.stopPropagation();
	},
	
	/**
	 * Спрятать кнопку. 
     * @public 
	 * @function
     * @memberOf widget.Button#
	 */
	hide : function() {
		var oldVisible = this.visible; 
		this.visible = false;
		if (this.visible != oldVisible) {
			this.element.addClass("hidden");
			this.onHide();
		}
	},
	
	/**
	 * Показать кнопку. 
     * @public 
	 * @function
     * @memberOf widget.Button#
	 */
	show : function() {
		var oldVisible = this.visible; 
		this.visible = true;
		if (this.visible != oldVisible) {
			this.element.removeClass("hidden");
			this.onShow();
		}
	},
	
	/**
	 * Функция отрабатывает после того, как элемент будет спрятан. 
     * @private 
	 * @function
	 */
	onHide : function() {
		if (this.config.listeners && this.config.listeners.hide) {
			this.config.listeners.hide(this, this.element);
		}
	},
	
	/**
	 * Функция отрабатывает после того, как элемент будет показан. 
     * @private 
	 * @function
	 */
	onShow : function() {
		if (this.config.listeners && this.config.listeners.show) {
			this.config.listeners.show(this, this.element);
		}
	},
	
	/**
	 * Возвращает текст на кнопке 
     * @public 
	 * @function
     * @memberOf widget.Button#
	 */
	getText : function() {
		return this.text; 
	},
	
	/**
	 * Устанавливает текст на кнопке 
     * @public 
	 * @function
     * @memberOf widget.Button#
     * @param {String} str Новый текст на кнопке.
	 */
	setText : function(str) {
		this.text = str; 
	},
	
	/**
	 * Устанавливает иконку на кнопке 
     * @public 
	 * @function
     * @memberOf widget.Button#
     * @param {String} cls Имя класса новой иконки на кнопке.
	 */
	setIconCls : function(cls) {
		this.iconCls = cls; 
	},
	
	/**
	 * Возвращает элемент DOM, принадлежащий виджету 
     * @public 
	 * @function
     * @memberOf widget.Button#
	 */
	getButtonEl : function() {
		return this.button; 
	},
	
	/**
	 * Возвращает элемент DOM, принадлежащий контейнеру компонента
	 * @public 
	 * @function
     * @memberOf widget.Button#
	 */
	getRenderContainer : function() {
		return this.renderContainer;
	}

});
